package com.brewdroid;

import java.io.File;
import java.util.ArrayList;

import android.app.Activity;
import android.content.ActivityNotFoundException;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnFocusChangeListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.Toast;

import com.brewdroid.db.DatabaseHelper;
import com.brewdroid.db.dao.AdjunctDAO;
import com.brewdroid.db.dao.HopDAO;
import com.brewdroid.db.dao.MaltDAO;
import com.brewdroid.db.dao.RecipeDAO;
import com.brewdroid.db.dao.StyleDAO;
import com.brewdroid.db.dao.YeastDAO;
import com.brewdroid.exception.RecipeNameTakenException;
import com.brewdroid.model.Ingredient;
import com.brewdroid.model.IngredientStep;
import com.brewdroid.model.Recipe;
import com.brewdroid.pdf.PDFUtil;


/**
 * Main brew droid activity
 * @author matt.richards
 *
 */
public class BrewDroidActivity extends Activity implements OnItemSelectedListener, OnClickListener, OnFocusChangeListener{
	
	boolean firstSelection = true;
	ArrayAdapter<String> recipeAdapter;
	DatabaseHelper dbHelper =null;
	public static final String NEW_RECIPE = "Create a new recipe";
	private Spinner styleSpinner;
	private ArrayList<String> styles;
	
	@Override
	public void onCreate(Bundle savedInstanceState) {
	    super.onCreate(savedInstanceState);
	    setContentView(R.layout.main);
	    try{
		    dbHelper=new DatabaseHelper(this);
		    dbHelper.createDataBase();
	    	dbHelper.openDataBase();
	    }
	    catch(Exception e)
	    {
	    	Log.e("com.brewdriod", "failed to create Sqlite DB", e);
	    }
	    
    	initRecipeSpinner();
    	
    	
    	
    	Button button = (Button)this.findViewById(R.id.viewPDFButton);
    	button.setOnClickListener(this);
    	
    	Button button2 = (Button)this.findViewById(R.id.saveButton);
    	button2.setOnClickListener(this);
    	
    	Button addButton = (Button)this.findViewById(R.id.addButton);
    	addButton.setOnClickListener(this);

    	TableLayout recipeFrame = (TableLayout)this.findViewById(R.id.subLayout);
    	recipeFrame.setVisibility(View.GONE);
    	
    	EditText og = (EditText)this.findViewById(R.id.og);
    	og.setOnFocusChangeListener(this);
    	
    	EditText fg = (EditText)this.findViewById(R.id.fg);
    	fg.setOnFocusChangeListener(this);
	}

	private void initRecipeSpinner() {
		ArrayList<Recipe> recipes = RecipeDAO.getRecipes(dbHelper);
		styles = StyleDAO.getAllStyles(dbHelper);
		
		
// 	    recipes=RecipeDAO.getRecipes(dbHelper); //recipes are already loaded above.
	 	ArrayList<String> rList = new ArrayList<String>();
	   	rList.add(NEW_RECIPE);
	   	for(Recipe i: recipes){
	   		rList.add(i.getName());
	   	}
	   	
	   	recipeAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, rList);
	    Spinner recipeSpinner = (Spinner)this.findViewById(R.id.spinner);
	    recipeSpinner.setOnItemSelectedListener(this);
    	recipeSpinner.setAdapter(recipeAdapter);
    	
    	ArrayAdapter<String> styleAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item,styles);
    	styleSpinner = (Spinner)this.findViewById(R.id.style);
    	styleSpinner.setAdapter(styleAdapter);
    	
	}
	
	private void createAndLaunchPDF(Recipe r)
	{
//    	this block creates a pdf and launches an intent for viewing it
    	PDFUtil pdf = new PDFUtil();
    	String path =pdf.createPDF(r);
    	
		Intent in = new Intent(Intent.ACTION_VIEW);
		File file = new File(path);
		Uri uriPath= Uri.fromFile(file);
		
		in.setDataAndType(uriPath, "application/pdf");
		
//		if the device doens't have the ability to show a pdf (IE they dont have a 
//		pdf viewer like adobe on phone it will bomb out.  Try handles this case
		try{
			//try to launch pdf
			startActivity(in);
		}
		catch(ActivityNotFoundException na)
		{
			Toast.makeText(this,"No PDF Viewer Installed on Device",Toast.LENGTH_SHORT).show();
		}
	}

	public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
		
		String txt = ((Spinner)this.findViewById(R.id.spinner)).getSelectedItem().toString();
		
		if(!txt.equalsIgnoreCase(NEW_RECIPE)){
						
			clearIngredientControls();
			TableLayout subLayout = (TableLayout)this.findViewById(R.id.subLayout);
			subLayout.setVisibility(View.VISIBLE);
			
			
			Recipe recipe = null;
			String selectedItem = (String) arg0.getItemAtPosition(arg2);
			recipe = RecipeDAO.getRecipeFromName(dbHelper, selectedItem);
			
//			update the style spinner to reflect the selected recipe's style
			styleSpinner.setSelection(styles.indexOf(recipe.getStyle()));
			//calls method to refresh og,fg,abv,description
			refreshRecipeControls(recipe);
			
			for(IngredientStep i : recipe.getIngredientList()){
				subLayout.addView(new RecipeItemRow(this, i, this,dbHelper));
			}

			Button button = (Button)this.findViewById(R.id.addButton);
			button.setOnClickListener(this);
			
			EditText name = (EditText)this.findViewById(R.id.name);
			name.setText(recipe.getName());
		}
		else
		{
			clearRecipeControls();
			clearIngredientControls();
			//add one row back to list
			addRow();
		}
	}
	
	private void clearIngredientControls() {
		TableLayout sublayout=(TableLayout)this.findViewById(R.id.subLayout);
		//remove all rows
		sublayout.removeAllViews();
	}

	private void clearRecipeControls() {
		((EditText)this.findViewById(R.id.name)).setText("");
		((EditText)this.findViewById(R.id.desc)).setText("");
		((EditText)this.findViewById(R.id.og)).setText("");
		((EditText)this.findViewById(R.id.fg)).setText("");
		((EditText)this.findViewById(R.id.abv)).setText("");
		
	}

	private void refreshRecipeControls(Recipe recipe) {
		((EditText)this.findViewById(R.id.desc)).setText(recipe.getDescription());
		((EditText)this.findViewById(R.id.og)).setText(Float.toString(recipe.getOriginalGravity()));
		((EditText)this.findViewById(R.id.fg)).setText(Float.toString(recipe.getFinalGravity()));
		((EditText)this.findViewById(R.id.abv)).setText(Float.toString(recipe.getAbv()));
	}

	public void addRow(){
		TableLayout subLayout = (TableLayout)this.findViewById(R.id.subLayout);
		subLayout.setVisibility(View.VISIBLE);
		subLayout.addView(new RecipeItemRow(this, null, this,dbHelper));
	}

	public void onNothingSelected(AdapterView<?> arg0) {
		
	}

	@Override
	public void onClick(View arg0) {
		
		Spinner spinner = (Spinner)this.findViewById(R.id.spinner);
		
		if(arg0.equals(findViewById(R.id.viewPDFButton))){
			Recipe r = RecipeDAO.getRecipeFromName(dbHelper, (String)(spinner.getSelectedItem()));
	    	createAndLaunchPDF(r);
		}
		else if(arg0.equals(findViewById(R.id.saveButton))){
			try{
				saveRecipe();
			}
			catch(RecipeNameTakenException e){
				e.printStackTrace();
			}
		}
		else if(arg0.equals(findViewById(R.id.addButton))){
			addRow();
		}
		else{
			TableRow row = ((TableRow)(arg0.getParent()));
			((TableLayout)((TableRow)arg0.getParent()).getParent()).removeView(row);
		}
	}
	
	public void saveRecipe() throws RecipeNameTakenException{
		//create a recipe instance 
		Recipe recipe = new Recipe();			
		
//		set all the attributes from values on the screen
		recipe.setName(((EditText)this.findViewById(R.id.name)).getText().toString());
		recipe.setStyle(styleSpinner.getSelectedItem().toString());
		recipe.setDescription(((EditText)this.findViewById(R.id.desc)).getText().toString());
		recipe.setAbv(Float.parseFloat((((EditText)this.findViewById(R.id.abv)).getText().toString())));
		recipe.setOriginalGravity(Float.parseFloat((((EditText)this.findViewById(R.id.og)).getText().toString())));
		recipe.setFinalGravity(Float.parseFloat((((EditText)this.findViewById(R.id.fg)).getText().toString())));
		
		TableLayout subLayout = (TableLayout)this.findViewById(R.id.subLayout);

		ArrayList<IngredientStep> list = new ArrayList<IngredientStep>();
		for(int i=0; i< subLayout.getChildCount(); i++){
			RecipeItemRow row = (RecipeItemRow) subLayout.getChildAt(i);
			IngredientStep is = new IngredientStep();
			
			Ingredient ingredient = null;
			
			String type = ((String)row.ingredientTypeSpinner.getSelectedItem());
			String ing = ((String)row.ingredientSpinner.getSelectedItem());
			
			if(type.equalsIgnoreCase(RecipeItemRow.MALT)){
				ingredient = MaltDAO.getMaltByName(dbHelper, ing);
			}
			else if(type.equalsIgnoreCase(RecipeItemRow.HOP)){
				ingredient = HopDAO.getHopByName(dbHelper, ing);
			}
			else if(type.equalsIgnoreCase(RecipeItemRow.YEAST)){
				ingredient = YeastDAO.getYeastByName(dbHelper, ing);
			}
			else if(type.equalsIgnoreCase(RecipeItemRow.ADJUNCT)){
				ingredient = AdjunctDAO.getAdjunctByName(dbHelper, ing);
			}
			is.setIngredient(ingredient);
			is.setQuantity(Double.valueOf(row.amount.getText().toString()));
			is.setUnitType(((String)row.units.getSelectedItem()));
			
			list.add(is);
		}
		
		Recipe r1 = RecipeDAO.getRecipeFromName(dbHelper, recipe.getName());
		
		
		recipe.setIngredientList(list);
		if(r1==null){
			RecipeDAO.addRecipe(dbHelper, recipe);
			initRecipeSpinner();	//need to reload the recipe spinner cause we just added a new recipe
		}
		else{
			RecipeDAO.updateRecipe(dbHelper, recipe);
		}
		
		
		Toast.makeText(this,"Recipe has been saved",Toast.LENGTH_LONG).show();
	
	}

	@Override
	public void onFocusChange(View v, boolean hasFocus) {
		boolean populated = false;
		EditText og = (EditText)this.findViewById(R.id.og);
		EditText fg = (EditText)this.findViewById(R.id.fg);
		
		if(exists(og.getText().toString()) && exists(fg.getText().toString())){
			EditText abv = (EditText)this.findViewById(R.id.abv);
			double originalG = Double.valueOf(og.getText().toString());
			double finalG = Double.valueOf(fg.getText().toString());
			double alcohol = (originalG - finalG) * 131;
			
			abv.setText(String.valueOf(alcohol).substring(0, 4));
			
		}
	}
	
	public boolean exists(String str){
		if(str != null && !str.equals("")){
			return true;
		}
		return false;
	}
}

